package org.homonoia.controller.core;

import java.util.ArrayList;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.log4j.Logger;
import org.homonoia.model.core.NodeStatus;

public class WorkerManager {

    private static final Logger log = Logger.getLogger(WorkerManager.class);

    volatile private Map<String, NodeStatus> workerList;
    private int timeoutPeriod;

    public WorkerManager(int timeoutPeriod) {
	this.workerList = new ConcurrentHashMap<String, NodeStatus>();
	this.timeoutPeriod = timeoutPeriod;
    }

    public void updateWorkerStatus(final String host, final NodeStatus status) {
	synchronized (workerList) {
	    workerList.put(host, status);
	    workerList.get(host).nodeUpdated();
	}
    }

    public final String getNextFreeNode() {
	synchronized (workerList) {
	    for (Map.Entry<String, NodeStatus> entry : workerList.entrySet()) {
		if (entry.getValue() == NodeStatus.AVAILABLE) {
		    return entry.getKey();
		}
	    }
	}
	return null;
    }

    public int getFreeNodeCount() {
	int count = 0;

	synchronized (workerList) {
	    for (Map.Entry<String, NodeStatus> entry : workerList.entrySet()) {
		if (entry.getValue() == NodeStatus.AVAILABLE) {
		    count++;
		}
	    }
	}

	return count;
    }

    public void removeWorker(final String host) {
	synchronized (workerList) {
	    workerList.remove(host);
	}
    }

    public final ArrayList<String> getTimedoutNodes() {
	ArrayList<String> timedoutNodes = new ArrayList<String>();
	Date currentTime = new Date();

	synchronized (workerList) {
	    for (Map.Entry<String, NodeStatus> entry : workerList.entrySet()) {
		if (currentTime.getTime() - entry.getValue().getUpdateTime().getTime() > timeoutPeriod) {
		    timedoutNodes.add(entry.getKey());
		}
	    }
	}

	return timedoutNodes;
    }
}
